﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.Web;
using ShopB2C.Enums;
using ShopB2C.Parameters;
using System.Web.Mvc;
using System.Linq;

namespace ShopB2C.Helper {
    public static class Methods {
        /// <summary>
        /// 通过文件扩展名获取文件 ContentType，例：jpg 的 ContentType 为 "image/pjpeg"
        /// </summary>
        /// <param name="extension">扩展名，例：.jpg</param>
        /// <returns>ContentType，例：image/pjpeg)</returns>
        public static string GetContentTypeByExtentsion(string extension) {
            string contentType = string.Empty;
            extension = extension.ToLower();

            SortedList<string, string> fileContents = new SortedList<string, string>();
            fileContents.Add(".bmp", "image/bmp");
            fileContents.Add(".jpg", "image/pjpeg");
            fileContents.Add(".jpe", "image/pjpeg");
            fileContents.Add(".jpeg", "image/pjpeg");
            fileContents.Add(".pdf", "application/pdf");
            fileContents.Add(".png", "image/x-png");
            fileContents.Add(".gif", "image/gif");
            fileContents.Add(".rar", "application/octet-stream");
            fileContents.Add(".7z", "application/octet-stream");
            fileContents.Add(".zip", "application/x-zip-compressed");

            if (fileContents.ContainsKey(extension)) {
                int index = fileContents.IndexOfKey(extension);
                contentType = fileContents.Values[index];
            }

            return contentType;
        }
        /// <summary>
        /// 计算机存储单位转换方法
        /// </summary>
        /// <param name="fileSize">大小，字节</param>
        /// <returns>转换后的文字表示，例：2G，20.02M</returns>
        public static string GetFileSize(int fileSize) {
            string size = string.Empty;
            double threePow = Math.Pow(1024, 3);
            double twoPow = Math.Pow(1024, 2);

            if (fileSize >= threePow) {
                size = Math.Round(fileSize / threePow * 1000 / 1000, 2) + "G";
            }
            if (fileSize >= twoPow && fileSize < threePow) {
                size = Math.Round(fileSize / twoPow * 1000 / 1000, 2) + "M";
            }
            if (fileSize >= 1024 && fileSize < twoPow) {
                size = Math.Round((double)(fileSize / 1024 * 1000 / 1000), 2) + "K";
            }
            if (fileSize >= 0 && fileSize < 1024) {
                size = Math.Round((double)fileSize, 2) + "B";
            }
            return size;
        }
        /// <summary>
        /// 分类模块参数传递格式化
        /// </summary>
        /// <param name="params">参数</param>
        /// <returns>ClassifyParam</returns>
        public static ClassifyParam FormatClassifyParams(string @params) {
            ClassifyParam cp = new ClassifyParam();
            if (!string.IsNullOrEmpty(@params)) {
                string[] pas = @params.Split('-');
                if (pas.Length == 10) {
                    try {
                        cp.ModuleKey = pas[0];
                        cp.ParentClassifyId = int.Parse(pas[1]);
                        cp.ClassifyPageNumber = int.Parse(pas[2]);
                        cp.ClassifyId = int.Parse(pas[3]);

                        cp.PropertyId = int.Parse(pas[4]);
                        cp.PropertyPageNumber = int.Parse(pas[5]);

                        cp.PropertyValId = int.Parse(pas[6]);
                        cp.PropertyValPageNumber = int.Parse(pas[7]);

                        cp.AutoSequence = int.Parse(pas[8]);
                        cp.DeleteIds = pas[9];
                    }
                    catch (Exception ex) {
                        throw new Exception("传入的参数有误!");
                    }
                }
            }
            return cp;
        }
        /// <summary>
        /// 商品展示参数传递格式化
        /// </summary>
        /// <param name="params">参数</param>
        /// <returns>ProductParam</returns>
        public static ProductParam FormatProductParams(string @params) {
            ProductParam pp = new ProductParam();
            if (!string.IsNullOrEmpty(@params)) {
                string[] pas = @params.Split('-');
                if (pas.Length == 6) {
                    try {
                        pp.Classify = pas[0].TrimStart('(').TrimEnd(')').Split(',')
                            .ToList().ConvertAll<int>(p => { return int.Parse(p); });
                        pp.PropertyVal = pas[1].TrimStart('(').TrimEnd(')').Split(',')
                            .ToList().ConvertAll<int>(p => { return int.Parse(p); });
                        pp.ShowType = (ProductShowType)int.Parse(pas[2]);
                        pp.SortFieldName = (ProductSortFieldNames)int.Parse(pas[3]);
                        pp.SortDescription = (SortDescriptions)(int.Parse(pas[4]) < 1 ? -1 : 1);
                        pp.PageIndex = int.Parse(pas[5]);
                    }
                    catch (Exception ex) {
                        throw new Exception("传入的参数有误!");
                    }
                }
            }
            return pp;
        }
        /// <summary>
        /// 商品评论参数传递格式化
        /// </summary>
        /// <param name="params">参数</param>
        /// <returns>CommentParam</returns>
        public static CommentParam FormatCommentParams(string @params) {
            CommentParam cp = new CommentParam();
            if (!string.IsNullOrEmpty(@params)) {
                string[] pas = @params.Split('-');
                if (pas.Length == 4) {
                    try {
                        cp.ProductId = int.Parse(pas[0]);
                        cp.SortFieldName = (CommentSortFieldNames)(int.Parse(pas[1]));
                        cp.PageIndex = int.Parse(pas[2]);
                        cp.GradeValue = (CommentGradeValues)(int.Parse(pas[3]));
                    }
                    catch (Exception ex) {
                        throw new Exception("传入的参数有误!");
                    }
                }
            }
            return cp;
        }
        /// <summary>
        /// 截取指定长度的字符串，区分单字节和双字节
        /// </summary>
        /// <param name="str">截取的字符串</param>
        /// <param name="length">截取的长度</param>
        /// <returns>指定截取长度后的字符串</returns>
        public static string SubString(string str, int length) {
            int trimLength = length * 2;
            byte[] strByte = Encoding.Unicode.GetBytes(str.Trim());
            if (strByte.Length <= trimLength) { return str; }
            int index = 0, currentLength = 0;
            for (int i = 0; i < length; i++) {
                index = (int)(i * 2 + 1);
                currentLength += strByte[index] > 0 ? 1 : 2;
                if (currentLength >= str.Length) { break; }
            }
            return str.Substring(0, currentLength < str.Length ? currentLength : str.Length) + " ...";
        }
        /// <summary>
        /// 弹出信息，Response.Writer 输出，默认后退
        /// </summary>
        /// <param name="info">信息文本</param>
        /// <param name="httpContext">HttpContext对象</param>
        public static void Alert(string info, HttpContextBase httpContext) {
            Alert(info, AlertType.GoBack, "-1", httpContext);
        }
        /// <summary>
        /// 弹出信息，Response.Writer 输出
        /// </summary>
        /// <param name="info">信息文本</param>
        /// <param name="alertType">弹出信息类型</param>
        /// <param name="stepORurl">后退步数或转向 URL 或 js 代码，例：history.go(-1), location.href='url'</param>
        /// <param name="httpContext">HttpContext对象</param>
        public static void Alert(string info, AlertType alertType, string stepORurl,
            HttpContextBase httpContext) {
            StringBuilder sb = new StringBuilder();
            sb.Append("<script language=\"javascript\" type=\"text/javascript\">");
            sb.AppendFormat("alert(\"{0}\");", info);
            switch (alertType) {
                case AlertType.RedirectToURL:
                    sb.AppendFormat("document.location.href=\"{0}\";", stepORurl);
                    break;
                case AlertType.GoBack:
                    sb.AppendFormat("history.go({0});", stepORurl);
                    break;
                case AlertType.ClosePage:
                    sb.Append("opener = null; window.close();");
                    break;
                case AlertType.SpecifiedProcess:
                    sb.Append(stepORurl);
                    break;
                default:
                    break;
            }
            sb.Append("</script>");
            httpContext.Response.Write(sb.ToString());
            httpContext.Response.End();
        }
        /// <summary>
        /// 获取指定枚举中，对应枚举的 Description 的 Attribute 的值，
        /// 与枚举的索引组成匿名对象加入到 List 中返回，new { Text = text, Value = value }
        /// </summary>
        /// <param name="enumType">指定枚举的 Type</param>
        /// <returns>List</returns>
        public static List<object> GetEnumsToList(Type enumType) {
            int value;
            string text;
            object[] attr;
            List<object> resultList = new List<object>();
            Type descriptionType = typeof(DescriptionAttribute);

            foreach (FieldInfo fi in enumType.GetFields()) {
                if (fi.FieldType.IsEnum) {
                    attr = fi.GetCustomAttributes(descriptionType, true);
                    text = attr.Length > 0 ? ((DescriptionAttribute)attr[0]).Description : fi.Name;
                    value = (int)enumType.InvokeMember(fi.Name, BindingFlags.GetField, null, null, null);
                    resultList.Add(new { Text = text, Value = value });
                }
            }

            return resultList;
        }
        /// <summary>
        /// 根据提供的 value 值, 从指定的 SelectList 中获得 text
        /// </summary>
        /// <param name="sl">SelectList</param>
        /// <param name="value">value</param>
        /// <returns>text</returns>
        public static string GetSelectListTextByValue(SelectList sl, string value) {
            return sl.First(s => { return s.Value == value; }).Text;
        }
        /// <summary>
        /// 根据提供的 text 值, 从指定的 SelectList 中获得 value
        /// </summary>
        /// <param name="sl">SelectList</param>
        /// <param name="text">text</param>
        /// <returns>value</returns>
        public static string GetSelectListValueByText(SelectList sl, string text) {
            return sl.First(s => { return s.Text == text; }).Value;
        }
    }
}
